-- ngx.say("dy_up")

local mp = require ('MessagePack')

local upserver = ngx.shared.upserver
local cjson = require("cjson")
local random = require('math').random
local randomseed = require('math').randomseed

local function _log(str) ngx.log(ngx.ERR, str) end

local getServerByType = function (typeName, servers)
  _log("typeName =" .. typeName)
  if 'table' ~= type(servers)  then
    _log("getServerByType server not table")
    return nil
  end

  if typeName == nil then
    _log("getServerByType nil " .. typeName)
    return nil
  end

  local list = servers[typeName]
  if not list then
    _log("getServerByType list nil")
    return nil
  end

  local len = table.getn(list)
  _log("len[" ..typeName .. "]=" .. len)
  randomseed(os.time())
  local targetServer = list[random(len)]
  -- _log("targetServer = " .. targetServer)
  return targetServer

end

local servers = upserver:get('servers')
if not servers then
  _log("servers not ready")
  return ngx.say("servers not ready")
end
servers = mp.unpack(servers)
local str_servers = cjson.encode(servers)
_log(str_servers)
-- ngx.say(str_servers)

-- get /type
_log("ngx.var.request_uri=" .. ngx.var.request_uri)
_log("ngx.var.host=" .. ngx.var.host)

local typeName, newUri = string.match(ngx.var.request_uri, '/(.-)/(.*)')
newUri = '/' .. newUri
_log("typeName=" .. typeName)
_log("newUri=" .. newUri)

local oMethod = ngx.req.get_method()
local proxyMethod
if oMethod=="GET" then proxyMethod = ngx.HTTP_GET
elseif oMethod=="POST" then proxyMethod = ngx.HTTP_POST
elseif oMethod=="PUT" then proxyMethod = ngx.HTTP_PUT
elseif oMethod=="DELETE" then proxyMethod = ngx.HTTP_DELETE
elseif oMethod=="OPTION" then proxyMethod = ngx.HTTP_OPTION
end
if not proxyMethod then _log("unsupport method" .. oMethod) return end
_log("proxyMethod=" .. proxyMethod)


local oheader = ngx.req.get_headers()
_log("method=" .. oMethod)

-- ngx.say("typeName=" , typeName)
local targetServer = getServerByType(typeName, servers)

if nil == targetServer then
  -- TODO code 503
  ngx.say("nil upstream server")
  return
end
_log("targetServer="..targetServer)


-- /proxy/http://ip:port/xxx
local upUrl='/proxy/' .. targetServer .. newUri
-- upUrl =/proxy/http://127.0.0.1:6001/echo/foo
_log("upUrl =" .. upUrl)
ngx.req.read_body()
-- local resp = ngx.location.capture(upUrl)
local resp = ngx.location.capture(upUrl,{
  method = proxyMethod,
  headers = oheader,
  body = body
})


if not resp then
    _log('===============nil resp===============')
    ngx.say("response error" ,err)
    return
end

-- status, headers, body
ngx.status = resp.status
_log('====ngx.status:'.. resp.status)
for k,v in pairs(resp.header) do
    _log('======header :' .. k .. v)
    if k ~= "Transfer-Encoding" and k ~= "Connection" then 
        ngx.header[k] = v
    end
end
ngx.say(resp.body)